package rjp.mutation;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import rjp.map.SantaMap;
import rjp.solution.MapConnection;
import rjp.solution.Solution;

public class ReverseSegmentMutation extends Mutation {

	private int segStart;
	private int segEnd;
	private SantaMap map;

	public ReverseSegmentMutation(int segStart, int segEnd, SantaMap map) {
		super(map);
		this.segStart=segStart;
		this.segEnd=segEnd;
		this.map=map;
	}

	@Override
	public Set<MapConnection> getAdditionalConnections(Solution solution) {
		Set<MapConnection> a=new HashSet<MapConnection>();
		if(this.segStart>0)
		{
			//System.out.println("Additional "+solution.getCityA(this.segStart-1)+" "+solution.getCityA(this.segEnd));
			a.add(new MapConnection(solution.getCityA(this.segStart-1), solution.getCityA(this.segEnd)));
		}
		if(this.segEnd<this.map.size()-1)
		{
			//System.out.println("Additional "+solution.getCityA(this.segStart)+" "+solution.getCityA(this.segEnd+1));
			a.add(new MapConnection(solution.getCityA(this.segStart), solution.getCityA(this.segEnd+1)));
		}
	
		return a;
	}

	@Override
	public Set<MapConnection> getObsoleteConnections(Solution solution) {
		Set<MapConnection> o=new HashSet<MapConnection>();
		if(this.segStart>0)
		{
			//System.out.println("Obsolete  "+solution.getCityA(this.segStart-1)+" "+solution.getCityA(this.segStart));
			o.add(new MapConnection(solution.getCityA(this.segStart-1), solution.getCityA(this.segStart)));
		}
		if(this.segEnd<this.map.size()-1)
		{
			//System.out.println("Obsolete  "+solution.getCityA(this.segEnd)+" "+solution.getCityA(this.segEnd+1));
			o.add(new MapConnection(solution.getCityA(this.segEnd), solution.getCityA(this.segEnd+1)));
		}
		return o;
	}

	@Override
	public Solution mutate(Solution solution) {
		ArrayList<Integer> newA=new ArrayList<Integer>(map.size());
		newA.addAll(solution.getSubListA(0, this.segStart));
		List<Integer> segment=solution.getSubListA(this.segStart, this.segEnd+1);
		Collections.reverse(segment);
		newA.addAll(segment);
		newA.addAll(solution.getSubListA(this.segEnd+1, this.map.size()));
		solution.setPathA(newA);
		return solution;
	}
	
	public String toString()
	{
		String s="Segment reverse from "+this.segStart+" to "+this.segEnd;
		return s;
	}

}
